//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#ifndef SMITHWATERMAN_H
#define SMITHWATERMAN_H

#include "libraries.h"
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
struct MaxScoreCell {

  int   maxIRow;
  int   maxICol;
  int   maxIScore;

  MaxScoreCell() {
    this->maxICol   = 0;
    this->maxIRow   = 0;
    this->maxIScore = 0;
  };

};

typedef struct MaxScoreCell MaxScoreCell;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
class SmithWaterman {

  private:

    String*                 seq1;
    String*                 seq2;
    String*                 alignment;
    TListE <String>*        regionsConserved;
    int                     numberRegions;

    int**                   matrix;

    int                     max_row;
    int                     max_col;
    float                   score;

    TListE <MaxScoreCell>*  listMaxCell;

  protected:

    void InvertSeq(String*);

  public:

    SmithWaterman();
    SmithWaterman(String*, String*);
    SmithWaterman(const SmithWaterman&);
    SmithWaterman(const SmithWaterman*);
    
    ~SmithWaterman();

    void                    SequencesIn(String*, String*);
    void                    SequencesOut(String*, String*);
    
    float                   Score();

    TListE <MaxScoreCell>*  ListMaxCell(void);
    
    void                    CleanSequences(void);
    
    String*                 ComputePairwiseAlignment(void);
    void                    ComputeMatrix(void);
    String*                 BuildOptimalAlignment(void);
    String*                 FindBestStrictLocalAlignment(void);
    int                     ComputeScore(void);

    String*                 GetConservedRegions(void);

    int                     ScoreInsertion(char);
    int                     ScoreSubstitution(char, char);
    int                     ScoreDeletion(char);
    
    void                    FindMaxScoreIterative(void);
    
};
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#endif
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
